const { staticPrefix } = require('@/config')

export const toString = Object.prototype.toString

export function Type(v: any) {
  return toString.call(v).replace(/\[object (.*)\]/, '$1')
}

export function isType(v: any, typeStr: any) {
  return Type(v).toLowerCase() === typeStr.toLowerCase()
}

export function isUndef(v: any) {
  return v === undefined || v === null
}

export function isDef(v: any) {
  return v !== undefined && v !== null
}

export function isEmpty(v: any) {
  return v === ''
}

export function deepCopy(v: any) {
  if (typeof v !== 'object') {
    return v
  }
  let copyV: any
  if (isType(v, 'Array')) {
    copyV = []
    for (let e of v) {
      e = deepCopy(e)
      copyV.push(e)
    }
  } else if (isType(v, 'Object')) {
    copyV = {}
    // eslint-disable-next-line prefer-const
    for (let [k, _v] of Object.entries(v)) {
      _v = deepCopy(_v)
      copyV[k] = _v
    }
  }
  return copyV
}

export function randomId() {
  return (Math.random() * 0xfffffff).toFixed().toString()
}

export function findItem(item: any, ...args: any) {
  for (const arg of args) {
    let hasItem = false
    for (const i of arg) {
      if (i === item) {
        hasItem = true
        break
      }
    }
    if (!hasItem) {
      return false
    }
  }
  return true
}

// 取交集
export function unite(...args: any[]) {
  if (args.length === 0) return args
  if (args.length === 1) return args[0]
  const uniteData = []
  for (let i = 0; i < args.length; i++) {
    const arg = args[i]
    const newArgs = [...args.slice(0, i), ...args.slice(i + 1)]
    for (const item of arg) {
      if (findItem(item, ...newArgs)) {
        uniteData.push(item)
      }
    }
  }
  return Array.from(new Set(uniteData))
}

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string}
 */
export function parseTime(time: any, cFormat: any) {
  if (arguments.length === 0) {
    return null
  }
  if (!time) return ''
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (typeof time === 'string') {
      if (time.indexOf('T')) {
        time = time.replace('T', ' ')
      }
      if (time.indexOf('Z')) {
        time = time.replace('Z', ' ')
      }
      if (/^[0-9]+$/.test(time)) {
        time = parseInt(time)
      } else {
        time = time.replace(/-/g, '/') // 处理safari与ie兼容
        if (time.indexOf('.') > -1) {
          // 处理 safari 中秒带小数点的兼容
          const tmpArr = time.split(' ')
          if (tmpArr.length === 2) {
            const his = tmpArr[1].split(':').map((v: any) => parseInt(v || 0))
            if (his.length > 0) {
              time = `${tmpArr[0]} ${his.join(':')}`
            }
          }
        }
      }
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
    /* const arr = time.split(/[- : \/]/)
    date = new Date(arr[0], arr[1] - 1, arr[2], arr[3], arr[4], arr[5]) */
  }
  interface objInter {
    [key: string]: string
  }
  const formatObj: objInter = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result: any, key: any) => {
    let value: any = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

//月份加减
export function addMonths(yearMonthDay: string, monthNum: number) {
  if (!yearMonthDay) return ''
  const arr = yearMonthDay.split('-') //2020-08-19或2020-08
  let year = parseInt(arr[0])
  let month = parseInt(arr[1])
  month = month + monthNum
  if (month > 12) {
    //月份加
    const yearNum = parseInt(`${(month - 1) / 12}`)
    month = month % 12 == 0 ? 12 : month % 12
    year += yearNum
  } else if (month <= 0) {
    //月份减
    month = Math.abs(month)
    const yearNum = parseInt(`${(month + 12) / 12}`)
    year -= yearNum
    if (month === 0) month = 12
  }
  const monthStr: string = month < 10 ? '0' + month : `${month}`
  return year + '-' + monthStr
}

// url路径格式化
export function formatURL(url: any, prefix = staticPrefix as any) {
  if (!url || typeof url !== 'string') return ''
  if (!prefix) return url
  const Expression = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/
  const objExp = new RegExp(Expression)
  if (objExp.test(url)) {
    return url
  }
  if (url.indexOf('/') !== 0) {
    if (prefix.substr(-1) !== '/') {
      prefix = `${prefix}/`
    }
  } else {
    if (prefix.substr(-1) === '/') {
      prefix = prefix.substr(0, prefix.length - 1)
    }
  }
  return `${prefix}${url}`
}
// JSON对象转formData
export function json2FormData(params: any) {
  const formData = new FormData()
  Object.keys(params).forEach((key) => {
    formData.append(key, params[key])
  })
  return formData
}

/*
 *序列化query
 */
export const serialize = (data: any) => {
  const list: any = []
  Object.keys(data).forEach((ele) => {
    list.push(`${ele}=${data[ele]}`)
  })
  return list.join('&')
}

/**
 * 参数处理
 * @param {*} params  参数
 */
export function tansParams(params: any) {
  let result = ''
  for (const propName of Object.keys(params)) {
    const value = params[propName]
    const part = encodeURIComponent(propName) + '='
    if (value !== null && typeof value !== 'undefined') {
      if (typeof value === 'object') {
        for (const key of Object.keys(value)) {
          if (value[key] !== null && typeof value[key] !== 'undefined') {
            const params = propName + '[' + key + ']'
            const subPart = encodeURIComponent(params) + '='
            result += subPart + encodeURIComponent(value[key]) + '&'
          }
        }
      } else {
        result += part + encodeURIComponent(value) + '&'
      }
    }
  }
  return result
}

// 验证是否为blob格式
export async function blobValidate(data: any) {
  try {
    const text = await data.text()
    JSON.parse(text)
    return false
  } catch (error) {
    return true
  }
}

/**
 * 创建下载
 * @param {blob} res 文件流
 * @param {string} fixedFileName  文件名称
 * */
export function createDownload(res: any, fixedFileName: any, isxlsx: Boolean = true) {
  if (!res || !res.data) return
  let fileName = ''
  if (fileName) {
    if (isxlsx) {
      fileName = `${decodeURIComponent(fixedFileName)}${parseTime(new Date(), '{y}{m}{d}{h}{i}{s}')}.xlsx`
    } else {
      fileName = decodeURIComponent(fixedFileName)
    }
  } else {
    fileName = res.headers['content-disposition']
    fileName = fileName.split(';')[1].split('filename=')[1]
    const fileNameUnicode = res.headers['content-disposition'].split('filename*=')[1]
    if (fileNameUnicode) {
      // 当存在 filename* 时，取filename* 并进行解码（为了解决中文乱码问题）
      fileName = decodeURIComponent(fileNameUnicode.split("''")[1])
    } else {
      fileName = decodeURIComponent(fileName)
    }
  }
  let blob = new Blob([res.data])
  if (isxlsx) {
    blob = new Blob([res.data], { type: 'application/vnd.ms-excel;charset=utf-8' })
  }
  if ('msSaveOrOpenBlob' in navigator) {
    window.navigator.msSaveOrOpenBlob(blob, fileName)
    return
  } else {
    const link = document.createElement('a')
    const objectURL = URL.createObjectURL(blob)
    link.download = decodeURI(fileName)
    link.href = objectURL
    document.body.appendChild(link)
    link.click()
    window.URL.revokeObjectURL(objectURL)
    document.body.removeChild(link)
  }
}

// 注册事件
export const SimpleEvents = {
  map: new Map(),
  registerEvent(key: string, cb: (data?: any) => void) {
    this.map.set(key, cb)
  },
  emit(key: string, params?: any) {
    if (this.map.has(key)) {
      this.map.get(key)(params)
    }
  }
}
export const initFormData = (src: any, dst: any) => {
  for (const [k, v] of Object.entries(dst)) {
    let value = src[k]
    const isBoolean = typeof v === 'boolean'
    const isArry = v instanceof Array
    if ((typeof value === 'string' || typeof value === 'number') && isBoolean) {
      value = [1, '1'].includes(value) ? true : false
    } else {
      if (isArry && value) {
        if (typeof value === 'string') {
          value = value.split(',').filter((e: any) => ![null, undefined, ''].includes(e))
        }
      }
    }

    const isObj = Object.prototype.toString.call(v) === '[object Object]'
    dst[k] = value !== undefined && value !== null ? value : isArry ? [] : isObj ? {} : ''
  }
}

// 电话号码中间四位隐藏
export const filterPhone = (phone: string) => {
  return phone && phone.replace(/^(\d{3})\d{4}(\d{4})/, '$1****$2')
}

// 跳转到拨打电话号码
export const onCallPhone = (phone: string) => {
  if (!phone) return
  window.location.href = `tel:${phone}`
}
// 数字千位格式化
export const toThousands = (num: any) => {
  if ([undefined, null, ''].includes(num)) return '0'
  return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
  // return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
